/**Copyright (c) 2008, Miika Vesti
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, 
 * with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above
 *    copyright notice, this list of conditions and the
 *    following disclaimer.
 * 2. Redistributions in binary form must reproduce the
 *    above copyright notice, this list of conditions
 *    and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the <NO ORGANIZATION> nor the names
 *    of its contributors may be used to endorse or promote
 *    products derived from this software without specific
 *    prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * */

var currentViewsKey = null;
var currentTorrentsKey = null;

var updateURL = 'rtpy/update';
var controlURL = 'rtpy/control';
var currentView = null;
var currentTorrent = null;
/* User interface update interval in milliseconds. */
var updateInterval = 1000;
var timer = null;

/* Define css classes for different torrent data cells. */
var torrentSpecs = {0: 'TorrentNameCell',
					1: 'TorrentStatusCell',
					2: 'TorrentSizeCell',
					3: 'TorrentDoneCell',
					4: 'TorrentDLCell',
					5: 'TorrentULCell',
					6: 'TorrentETACell',
					7: 'TorrentDownloadedCell',
					8: 'TorrentUploadedCell',
					9: 'TorrentRatioCell',
					10: 'TorrentPeersCell'};

/* Start updating user interface. */
startTimer();

function getData(dataSource, callback) {
	var xmlHttp = null;
	if (window.XMLHttpRequest) {
		xmlHttp = new XMLHttpRequest();
	} else if (window.ActiveXObject) {
		try {
			xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch(e) {
			try {
				xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				alert("Your browser does not support AJAX!");
				return null;
			}
		}
	}
	if (xmlHttp) {
		xmlHttp.open("GET", dataSource);
		xmlHttp.onreadystatechange = function() {
			if(xmlHttp.readyState==4) {
				obj = JSON.parse(xmlHttp.responseText);
				callback(obj);
				delete xmlHttp;
				xmlHttp = null;
			}
		}
		xmlHttp.send(null);
	}
}

function startTimer() {
	timer = setTimeout('updateUI()', 0);
}

function stopTimer() {
	clearTimeout(timer);
}

function updateUI() {
	if(currentTorrent!= null) info_hash = currentTorrent;
	query = updateURL + '?';
	if(currentView != null) {
		query = query + 'view=' + currentView.replace('view_', '');
		if(currentTorrent != null) {
			query = query + '&info_hash=' + currentTorrent;
		}
	}
	getData(query, updateUICallback);
	timer = setTimeout('updateUI()', updateInterval);
}

function updateUICallback(obj) {
	viewsKey = obj.views.key;
	viewsData = obj.views.data;
	viewsSelect = obj.views.select;
	torrentsKey = obj.torrents.key;
	torrentsData = obj.torrents.data;
	torrentsSelect = obj.torrents.select;
	detailsKey = obj.details.key;
	detailsData = obj.details.data;
	
	if(viewsKey != currentViewsKey) {
		insertViews(viewsData);
		currentViewsKey = viewsKey;
	}
	if(viewsSelect != null) selectView('view_' + viewsSelect);
	
	if(torrentsKey == null || torrentsKey != currentTorrentsKey) {
		insertTorrents(torrentsData);
		currentTorrentsKey = torrentsKey;
	} else {
		updateTorrents(torrentsData);
	}
	if(torrentsSelect) selectTorrent(torrentsSelect);
	updateDetails(detailsData);
}

function addTorrent() {
}

function deleteTorrent() {
}

function startTorrent() {
	/* Return, if no torrent is selected. */
	if(currentTorrent == null) return;
	/* Pause update process when calling control URL. */
	stopTimer();
	el = document.getElementById(currentTorrent);
	el.cells[1].childNodes[0].innerHTML = 'Starting';
	startQuery = controlURL + '?action=start&info_hash=' + currentTorrent;
	getData(startQuery, function(){});
	t = setTimeout('startTimer()', 2000);
}

function stopTorrent() {
	/* Return, if no torrent is selected. */
	if(currentTorrent == null) return;
	/* Pause update process when calling control URL. */
	stopTimer();
	el = document.getElementById(currentTorrent);
	el.cells[1].childNodes[0].innerHTML = 'Stopping';
	stopQuery = controlURL + '?action=stop&info_hash=' + currentTorrent
	getData(stopQuery, function(){});
	t = setTimeout('startTimer()', 2000);
}

function about() {
}

/**This function is called when user clicks view in the views
 * table (sidebar, left).
 * */
function selectView(view) {
	if(currentView != null) {
		/* Try-catch for safety. Torrent might have been deleted from elsewhere. */
		try {
			el = document.getElementById(currentView);
			el.className = el.className.replace(' ViewRowFocus', '');
		} catch(e) {}
	}
	obj = document.getElementById(view);
	obj.className = obj.className + ' ViewRowFocus';
	currentView = obj.id;
}

/**This function is called when user click torrent in the
 * torrents table.
 * */
function selectTorrent(info_hash) {
	if(currentTorrent != null) {
		/* Try-catch for safety. Torrent might have been deleted from elsewhere. */
		try {
			el = document.getElementById(currentTorrent);
			el.className = el.className.replace(' TorrentRowFocus', '');
		} catch(e) {}
	}
	obj = document.getElementById(info_hash);
	obj.className = obj.className + ' TorrentRowFocus';
	currentTorrent = obj.id;
}

function insertViews(views) {
	viewtable = document.getElementById('views')
	viewBody = viewtable.tBodies[0];
	viewBody.innerHTML = '';
	var counter = 0;
	for(i in views) {
		tr = viewBody.insertRow(counter);
		tr.className = 'ViewRow';
		tr.id = 'view_' + views[i];
		tr.setAttribute('onclick', 'selectView(this.id);');
		td = tr.insertCell(0);
		td.className = 'ViewCell';
		span = document.createElement('span');
		span.className = 'ViewDataEntry';
		span.innerHTML = views[i];
		td.appendChild(span);
		counter++;
	}
	/*Previously selected View has been removed from somewhere else and
	 * is not available anymore. */
	if(document.getElementById(currentView) == null) {
		currentView = 'view_' + views[0];
		selectView[currentView];
	}
}

/**Regenerate whole content of torrents table.
 * This function should be called every time
 * a view is selected from views table.
 * */
function insertTorrents(torrents) {
	torrenttable = document.getElementById('torrents');
	torrentBody = torrenttable.tBodies[0];
	torrentBody.innerHTML = '';
	var counter = 0;
	for(i in torrents) {
		tr = torrentBody.insertRow(counter);
		tr.className = 'TorrentRow';
		tr.setAttribute('onclick', 'selectTorrent(this.id);');
		tr.id = torrents[i][0];
		
		for(j in torrentSpecs) {
			td = tr.insertCell(j);
			td.className = 'TorrentCell ' + torrentSpecs.j;
			span = document.createElement('span');
			span.className = 'ViewDataEntry';
			span.innerHTML = torrents[i][parseInt(j) + 1];
			td.appendChild(span);
		}
		counter++;
	}
	/*View was changed and previously selected torrent
	 * does not belong to it. */
	if(document.getElementById(currentTorrent) == null) {
		currentTorrent = null;
	}
}

/**Update torrents table's data cells. Only cell data
 * is updated, not the whole inner HTML.
 * 
 * This method should be called regularly to update
 * torrent statistics. 
 * */
function updateTorrents(torrents) {
	torrenttable = document.getElementById('torrents');
	torrentBody = torrenttable.tBodies[0];
	for(i in torrents) {
		info_hash = torrents[i][0];
		tr = document.getElementById(info_hash);
		for(j in torrentSpecs) {
			span = tr.cells[parseInt(j)].childNodes[0];
			span.innerHTML = torrents[i][parseInt(j) + 1];
		}
	}
}

function updateDetails(torrent) {
}

